#-------------------------------------------------------------------------------
# Name:        vsctype
# Purpose:     VSC Type
#
# Author:      SUPER_紫电  QQ:911344755
#
# Created:     08/09/2022
# Copyright:   (c) SUPER_紫电 2022 All rights reserved.
# Licence:     <Modified BSD License>
#-------------------------------------------------------------------------------

from enum import Enum
from ctypes import POINTER, Structure, c_ubyte, c_ushort, c_ulong, c_void_p
from ctypes.wintypes import USHORT, ULONG, PWORD, PDWORD

BYTE = UCHAR = c_ubyte
PBYTE = POINTER(BYTE)

FEATENB = 1
FEATDIS = 2

SET_FEATURE = 1
RD_FEATURE  = 2

SMART_CTRLKEY = 0xBE # VSC Control pass-thru key
SMART_DATAKEY = 0xBF # VSC Data pass-thru key

#-----------------------------------------------------------------------------
# VSC ACTION CODES
#-----------------------------------------------------------------------------
AC_RDWRRESFILE  = 8 # Read/Write Resident file
AC_CHKFILEID    = 9 # Check Reserved resident file
AC_RDWRMTBL     = 11 # Read/write memory table
AC_RDWRCHS      = 12 # Read/Write CHS segment
AC_GETDRVTBL    = 13 # Get Drive Data Tables
AC_FEATCTRL     = 14 # Feature Control Command
AC_ERATETBL     = 15 # Read/Reset Error Rate Table
AC_RDWRWEDGE    = 17 # Read/Write Wedge
AC_VIRTSK       = 18 # Virtual Seek to Track
AC_RDWRMEM      = 19 # Read/Write Memory Location
AC_RDWRBUFEXT   = 20 # Read/Write Buffer Extended
AC_LBATOCHS     = 21 # Translate logical lba to chs address
AC_CHSTOLBA     = 22 # Translate physical CHS to LBA address
AC_SERVOCTRL    = 23 # Servo Control Functions
AC_FMTUNIT      = 24 # Format Unit
AC_EXECFILE     = 25 # Execute File
AC_RDWRLONG     = 26 # Read/Write Long
AC_SECTCTRL     = 27 # Sector Control
AC_RESET        = 28 # Initiate power on reset
AC_RDWRVFYLBA   = 29 # Read/Write/Verify LBA segment
AC_WRALLWITHIDS = 30 # Write All with ID's
AC_EXPCTRL      = 31 # Exception control
AC_TRKOFT       = 32 # Set Track offset
AC_RDWRDEV      = 33 # Read/write device
AC_ERRINJ       = 34 # Error Injection
AC_LOGSK        = 35 # Logical Seek
AC_RWERASEFLASH = 36 # Read/Write/Erase Flash
AC_WRITETRK     = 37 # Write Track
AC_RDWRTPI      = 38 # Read/Write TPI Parameters
AC_HDDEPOPCTRL  = 39 # Head Depop Control
AC_FILEMGR      = 40 # File System Magnager
AC_PSTTEST      = 41 # PST Test Mode
AC_RDWRFIELD    = 42 # Read/Write Field
AC_CHWB2PSN     = 44 # Translate CHWB to PSN
AC_EXECDIAG     = 46 # Execute a diagnostic (previously downloaded)
AC_GAINCALCTRL  = 47 # VSC Gain Cal Control
AC_FMTSELECT    = 48 # VSC Format Selection
AC_RDWRRSVDLBA  = 50 # VSC Read/Write Reseved LBA
AC_RLBATOCHS    = 51 # VSC Translate Resrved RLBA to Virtual CHS
AC_DFHCONTROL   = 52 # Control of DFH DAC parameters
AC_PWL          = 53 # PWL Monitor Feature Control Command
AC_XLATTRKADDR  = 54 # Translate Track Address
AC_UCCMDRVCFG   = 55 # UCCM Drive Configuration

#-----------------------------------------------------------------------------
# Defines for Read/Write Memory Table
#-----------------------------------------------------------------------------
mtZone      = 0 # Zone Table (Memory Table)
mtDrvCfg    = 1 # Drive Configuration (Memory Table)
mtChannel   = 2 # Read Channel Table (Memory Table)
mtWrCurr    = 3 # Write Current Table (Memory Table)
mtDRM       = 5 # DRM Period Table (Memory Table)
mtHDA       = 6 # HDA Params Table (Memory Table)
mtDRMOL     = 7 # DRM Offline Timers (Memory Table)
mtMRBias    = 9 # MR Bias Table (Memory Table)
mtMRJog     = 10 # MR Jog Table (Memory Table)vmtMRHdLin
mtMRLin     = 11 # MR Head Linearity (Memory Table)
mtMRHDRes   = 12 # MR Head Resistance (Memory Table)
mtEventLog  = 13 # Event Log Table
mtCacheRelo = 14 # Cache Relocation (Memory Table)
mtSeekPro   = 15 # Seek Profile Performance

e28BitATACmd = 0
e48BitATACmd = 1
eVSCKeyCmd   = 2
eVSCDataCmd  = 3

#-----------------------------------------------------------------------------
# ENUMS (VSC FUNCTION CODES, FEATURES, ETC)
#-----------------------------------------------------------------------------

# Function code for Read/Write Reserved File (Action code 8)
class FC_RWResFile(Enum):
    eRDRESFILE              = 1  # Read Reserved File
    eWRRESFILE              = 2  # Write Reserved File
    eDNSTATICFILE           = 3  # Download from media to static file
    eUPSTATICFILE           = 4  # Upload from static file to media
    eCreateFile             = 5  # Create file
    eDeleteRemoveFile       = 6  # Delete File
    eMarkFileBad            = 7  # Mark file Bad, Set ID to "bad" id and don't free space
    eReturnAttribs          = 8  # Return file attributes
    eSetAttribs             = 9  # Set file attributes
    eReadSingleCopy         = 10 # Read single copy of file
    eWriteSingleCopy        = 11 # Write single copy of file
    eReturnFileInfo         = 12 # Return file info
    eReadPartialFile        = 13 # Read Partial file
    eWritePartialFile       = 14 # Write Partial file
    eReadPartialByte        = 15 # Read Partial file
    eWritePartialByte       = 16 # Write Partial file
    eReadSinglePartialFile  = 17 # Read single partial file without checksum.
    eWriteSinglePartialFile = 18 # Write single partial file without checksum.

class FC_File_Attribute(Enum):
    eATTR_REGION_0       = 0
    eATTR_REGION_1       = 1
    eATTR_REGION_2       = 2
    eATTR_REGION_3       = 3
    eATTR_REGION_4       = 4
    eATTR_REGION_5       = 5
    eATTR_REGION_6       = 6
    eATTR_REGION_7       = 7
    eATTR_FLASH          = 8
    eATTR_RESERVED0      = 9
    eATTR_RD_ONLY        = 10
    eATTR_CHKSUM         = 11
    eATTR_HEADER         = 12
    eATTR_PLHOLDER       = 13
    eATTR_STATICFL       = 14
    eATTR_PTM            = 15
    eATTR_PTSM           = 16
    eATTR_TRANSIENT      = 17
    eATTR_FILECREATE     = 18
    eATTR_FILEPRESERVE   = 19
    eATTR_FIELDCODE      = 20
    eATTR_LASTAVAILSPACE = 21
    eATTR_RESERVED5      = 22
    eATTR_RESERVED6      = 23
    eATTR_RESERVED7      = 24
    eATTR_RESERVED8      = 25
    eATTR_RESERVED9      = 26
    eATTR_RESERVED10     = 27
    eATTR_RESERVED11     = 28
    eATTR_RESERVED12     = 29
    eATTR_RESERVED13     = 30
    eATTR_RESERVED14     = 31
    eATTR_RESERVED15     = 32

# Function code for Read/Write Memory Table (Action code 11)
class FC_RWMemTbl(Enum):
    eRDMEMTABLE      = 1 # Read Memory table
    eWRMEMTABLE      = 2 # Write Memory table
    eWRIMDMEMTABLE   = 3 # Write Immediate Memory table
    eRDSTATICFILE    = 4 # Read Static File
    eWRSTATICFILE    = 5 # Write Static File
    eWRIMDSTATICFILE = 6 # Write Immediate Static File
    eRDDRMGROUP      = 7 # Read DRM Counters Group
    eWRDRMGROU       = 8 # Write DRM Counters Group
    eWRIMDDRMGROUP   = 9 # Write Immediate DRM Counters Group
    ePERIODLOGSUM    = 10 # Sum Period logs

# Read/Write CHS Segment (Action code 12)
class FC_RWCHS(Enum):
    eRDCHS_WITHRELO    = 1
    eWRCHS_WITHRELO    = 2
    eRVCHS             = 3
    eRepWRCHS          = 4
    eRDCHS_WITHOUTRELO = 5
    eWRCHS_WITHOUTRELO = 6
    eRDCHS_RAW         = 7
    eWRCHS_RAW         = 8
    eVCHS_LOSSY        = 9
    eWRCHS_PATR        = 10

# Get Drive Data Tables (Action code 13)
class FC_GetDrvTbl(Enum):
    eDrvTbl          = 1  # Drive Physical Parameters
    eTAATbl          = 2  # TAA Table
    eWrSenseTbl      = 3  # Write Sensitivity Table
    eRROTbl          = 4  # RRO Table
    eZoneTbl         = 5  # LBA Zone Table
    eWedZoneTbl      = 6  # Wedge ZOne Table
    eDrvRdyTbl       = 7  # Drive Ready Table
    eMRRTbl          = 8  # MR Resistance Table
    eVSCTbl          = 9  # VSC Implementation Vector
    eCRTbl           = 10 # Cache Relo Table
    eSkLatTbl        = 11 # Seek Latency Table
    eMmsCritparam    = 12 # MMS Critical params
    ePhysZoneTbl     = 13 # Physical Zone Table - VDT only
    eDummy           = 14 # dummy for now
    eMmsDFHparam     = 15 # MMS DFH params
    eMmsDFHLiveparam = 16 # MMS DFH live params

# Feature code for Feature Control Command  (Action code 14)
class FC_FeatureCtrl(Enum):
    eClearDRMLog          = 1
    eClearFactoryFile     = 2
    eInitODTAAWS          = 3
    eInitRRO              = 4
    eSetDRM               = 5
    eCalibDrvTemp         = 6
    eRdChannelCourseTune  = 7
    eWearLeveling         = 8
    eSetOLIdleTime        = 9
    eSetOLSpinTime        = 10
    eClrDebugStop         = 11
    eDRMPeriodLogShift    = 12
    eDRMFlush             = 13
    eSmartBackDoor        = 14
    eBackgroundActivity   = 15
    eDtempSampling        = 16
    eMeasureMRResistance  = 17
    ePSTMode              = 18
    eFlashCode            = 19 # DX only
    eSetDebugStop         = 20
    eClrDRMSection        = 21
    eDestrokeUpstroke     = 22
    eDriveFormat          = 23
    eSmartTestMode        = 24
    eStdbyTmr10MinMinimum = 25
    eSeekLatencyData      = 26
    eEmulatorBreak        = 27
    eAutoFlushTimer       = 28
    eEnableExtLBA         = 29
    eIdle1Time            = 30
    eIdle2Time            = 31
    eIdle3Time            = 32
    ePowerManagementState = 33
    eMINUS4_CYL_EMUL      = 34
    eAdvancedPowerManagementLevel = 35
    eTestID                   = 36
    eSmartAttributeIdNewValue = 37
    eSmartAttributeIdSetMask  = 38
    eSmartAttributeIdClrMask  = 39
    eSscState                 = 40
    eSataStaggeredSpinupState = 41
    eSataInterfaceSpeedState  = 42
    ePowerUpInStandby         = 43
    eServoFlexBiasFilter      = 44
    eOscillatorState          = 45
    eDFHCalibration           = 46
    ePhyConfiguration         = 47
    eSmartSetAttrStatus       = 48 # Set Smart Attribute Status flags
    eSmartSetAttrThreshold    = 49 # Set Smart Attribute Threshold value
    eCFConfigSettings         = 50
    eAltComresetHandler       = 51 # Configure state of alternate comreset handler.
    eDummy52                  = 52
    eDummy53                  = 53
    eDummy54                  = 54
    eDummy55                  = 55
    eDummy56                  = 56
    eDummy57                  = 57
    eSetAggressiveAOLTime     = 58 # Set Aggressive AOL Timer

# Enums for Feature Control Clear DebugStop
class FC_ClearDebugStop(Enum):
    eClrDBSRam = 1 # Clear debug stop in ram
    eClrDBSAll = 2 # clear debug stop both in memory and file 0x2d

# Function code for Read/Reset Error Rate Table (Action code 15)
class FC_ErrRateTbl(Enum):
    eResetErate    = 1
    eGetErate      = 2
    eGetResetErate = 3

# Settle Mode used by Logical Seek Command (Action code 18/35)
class FC_SeekTrack(Enum):
    eSK_RDLMT        = 0 # Settle on trk using servo read limits and wait for sk complete.
    eSK_WRLMT        = 1 # Settle on trk using servo write limits and wait for sk complete.
    eSK_RDLMT_NSC    = 2 # Settle on trk using servo read limits and do not wait for sk complete.
    eSK_WRLMT_NSC    = 3 # Settle on trk using servo write limits and do not wait for sk complete.
    eSK_RDLMT_NxTrks = 4 #
    eSK_WRLMT_NxTrks = 5 #
    eSK_RDASYNC      = 6 # mode 6
    eSK_WRASYNC      = 7 # mode 7
    eSK_SRDLMT       = 8 # mode 8, settle on track using servo read limit and wait for sk complete
    eSK_SWRLMT       = 9 # mode 9, settle on track using servo write limit and wait for sk complete


# Function code used by Read/Write Memory Command (Action Code 19)
class FC_RWMem(Enum):
    eRDMEM = 1 # Read memory address
    eWRMEM = 2 # Write memory address

# Function code for read/write buffer ext (Action code 20)
class FC_RWBufEx(Enum):
    eRBX_CACHE    = 1
    eWBX_CACHE    = 2
    eRBX_DRAM     = 3
    eWBX_DRAM     = 4
    eRBX_TRANSOVL = 5
    eWBX_TRANSOVL = 6
    eRBX_PERMOVL  = 7
    eWBX_PERMOVL  = 8
    eRBX_PST      = 9
    eWBX_PST      = 10
    eRBX_PST_DATA = 11
    eWBX_PST_DATA = 12
    eWBX_SOVL     = 13
    eWBX_COVL     = 14

# Servo Control Functions (Action code 23)
class FC_ServoCtrl(Enum):
    ServoSpinUp  = 1 # Servo Spinup
    ServoSpinDn  = 2 # Servo Spin Down
    ServoActInit = 3 # Servo actuator Init
    ServoCal     = 4 # Servo Calibration
    ServoPark    = 5 # Servo Park
    ServoTrace   = 6 # Servo Trace feature
    ServoTableId = 7 # Servo Return Table Data

# Function code for Format Unit/Format Reserved (Action code 24)
class FC_FmtUnit(Enum):
    eFMTRESERVED = 1 # format reserved
    eFMTUNIT     = 2 # Format Unit
    eMERGPG      = 3 # Merge P & G List
    eCLRGLIST    = 4 # Clear Glist & Relolist
    eREMERGPG    = 5 # ReMerge P & G List

# Function code for Execute File command (Action code 25)
class FC_ExecFile(Enum):
    eDnloadExec          = 1
    eExecFileInMemory    = 2
    eExecPST             = 3
    eExecCaptive         = 4
    eInitDownloadCodePTM = 5

# Function code for Initiate Power On Reset (Action code 28)
class FC_Reset(Enum):
    eIMMEDPOR    = 1 # Reset immediate
    eSPINDOWNPOR = 2 # Spindown and reset
    eWARMSTART   = 3 # Soft Reset

# Function code used by Read/Write/Erase Flash command (Action code 36)
class FC_Flash(Enum):
    eRdFlash    = 1 # Read Flash
    eWrFlash    = 2 # Write Flash
    eEraseFlash = 3 # Erase Flash

# Function code for File system manager command (Action code 40)
class FC_FileMgr(Enum):
    eValidateFileSystem = 1
    eDefragment         = 2
    eListdirectory      = 3
    eExpendRSVD         = 4

# Read/Write/Verify Reseved LBA command (Action code 50)
class FC_RWLBA(Enum):
    eRDRLBA  = 1 # Read Reserved LBA
    eWRRLBA  = 2 # Write Reserved LBA
    eVfyRLBA = 3 # Verify Reserved LBA

# Function code for Drive Configuration command (Action code 55)
class FC_DriveConfig(Enum):
    eSetProcess1Mode    = 1
    eSetUserKeyMode     = 2
    eSetUserPayloadMode = 3
    eGetMode            = 4
    eVerify             = 5
    eGetVerInfo         = 6
    eSetRev             = 7
    eGetFeatKey         = 8
    eGetAC55Detail      = 9
    eLoadDataFile       = 10
    eGetUserKeyMode     = 11
    eSetProcess2Mode    = 12

# Enums for Feature Control Alternate COMRESET
class FC_AltComreset(Enum):
    eDisAltComreset = 1 # disable the alternate comreset method
    eEnAltComreset  = 2 # enable the alternate comreset method

class FC_FileHeaderType(Enum):
    eHdrGeneric = 1
    eHdrPST     = 2
    eHdrOVerlay = 3
    eHdrFlash   = 4

class Dir_Sector_Header(Structure):
    _fields_ = [
        ('FileHeaderSz', UCHAR),
        ('FileSize', USHORT),
        ('NumEnries', USHORT),
    ]

class File_Entry(Structure):
    _pack_ = 1
    _fields_ = [
        ('EntrySize', UCHAR),
        ('NumCopies', UCHAR),
        ('FileID', USHORT),
        ('FileSize', USHORT),
        ('FileAttrib', ULONG),
        ('OffsetCopy0', ULONG),
        ('OffsetCopy1', ULONG),
    ]

class Flash_Dir_Sector_Header(Structure):
    _fields_ = [
        ('FileHeaderSz', UCHAR),
        ('FileSize', USHORT),
        ('NumEnries', UCHAR),
    ]

class Flash_File_Entry(Structure):
    _pack_ = 1
    _fields = [
        ('EntrySize', UCHAR),
        ('NumCopies', UCHAR),
        ('FileID', USHORT),
        ('FileSize', USHORT),
        ('FileAttrib', ULONG),
        ('OffsetCopy0', ULONG),
        ('OffsetCopy1', ULONG),
    ]

class Reserve_Region_Table_Header(Structure):
    _pack_ = 1
    _fields_ = [
        ('next_entry_offset', UCHAR),
        ('num_regions', UCHAR),
        ('file_id', USHORT),
        ('active_regions', UCHAR),
    ]

class Reserve_Region_Entry(Structure):
    _pack_ = 1
    _fields_ = [
        ('region_size', ULONG),
        ('region_address', ULONG),
    ]

# This starts at byte offset 256 of drvtbl data.
class Drv_Data_Tbl_Overlay(Structure):
    _pack_ = 1
    _fields_ = [
        ('DCM', UCHAR*36),             # 36  DCM string=36 bytes
        ('FTSDate', UCHAR*12),         # 12  This is original drive built date=12 bytes
        ('FTSReconfigDate', UCHAR*12), # 12  This is drive reconfiguration date = 12 bytes
    ]

# Drive Data Table
class Drv_Data_Tbl(Structure):
    _pack_ = 1
    _fields_ = [
        ('Ver',USHORT),                   # 2    offset=0.  Format version
        ('CtrlFWRev', UCHAR*8),           # 8    offset=2.  controller firmware rev. Total=8 bytes
        ('ServoFWRev', UCHAR*8),          # 8    offset=10. servo firmware rev. Total = 8 bytes
        ('OvlFWRev', UCHAR*8),            # 8    offset=18. overlay firmware rev. Total=8 bytes
        ('ProdID', USHORT),               # 2    offset=26. Product byte(LSB) and secondary product byte (MSB)
        ('PlatCnt', UCHAR),               # 1    offset=28. Drive platter count
        ('PhyHdCnt', UCHAR),              # 1    offset=29. Physical number of hds including depop hds.
        ('VirHdCnt', UCHAR),              # 1    offset=30. Virtual head count(actual no. of hds used)
        ('Depops', UCHAR),                # 1    offset=31. Bit map value. Bit 0= head 0. Bit set=head used
        ('DrvType', UCHAR),               # 1    offset=32. Drive type
        ('ZoneCnt', UCHAR),               # 1    ofsfet=33. Num. of zones including reserved zone
        ('ServoCnt', USHORT),             # 2    offset=34. No. of servo wedges
        ('RsvdCylCnt', USHORT),           # 2    offset=36. Virtual no. of negative cylinders
        ('SpindleRPM', USHORT),           # 2    offset=38. Spindle RPM
        ('UserCylCnt', ULONG),            # 4    offset=40. No. of user cylinders
        ('CylWedgeSkew', UCHAR),          # 1    offset=44. Cylinder skew
        ('HdWedgeSkew', UCHAR),           # 1    offset=45. Head skew
        ('ClusterSkew', UCHAR),           # 1    offset=46. Cluster Skew
        ('CodeRes', UCHAR),               # 1    offset=47. Code Residence
        ('PCBAType', UCHAR),              # 1    offset=48. PCBA Type
        ('InterfaceTyp', UCHAR),          # 1    offset=49. Interface type
        ('CtlrChipVend', USHORT),         # 2    offset=50. Controller chip Vendor
        ('CtrlChipRev', USHORT),          # 2    offset=52. Controller chip rev
        ('UpVend', USHORT),               # 2    offset=54. MicroP Vendor
        ('UpRev', USHORT),                # 2    offset=56. MicroP Rev
        ('ChnChipVend', USHORT),          # 2    offset=58. Channel Chip Vendor
        ('ChnChipRev', USHORT),           # 2    offset=60. Channel chip Rev
        ('PreampVend', USHORT),           # 2    offset=62. Preamp Vendor
        ('PreampRev', USHORT),            # 2    offset=64. Preamp Rev
        ('PwrICVend', USHORT),            # 2    offset=66. Power IC vendor
        ('PwrICRev', USHORT),             # 2    offset=68. Power IC Rev
        ('OTFIntlv', UCHAR),              # 1    offset=70. No. of interleaves in OTF ECC Corr
        ('NumOTF',UCHAR),                 # 1    offset=71. Number of bytes corrected by OTF
        ('BurstCnt', USHORT),             # 2    offset=72. Number of bytes corrected by FW burst corr.
        ('ECCBytes', UCHAR*2),            # 2    offset=74. No. of ecc bytes in read/write long sector
        ('MaxVSCTx', USHORT),             # 2    offset=76. maximum VSC transfer data count
        ('FormatRev', UCHAR*8),           # 8    offset=78. surface format version. Total=8 bytes
        ('RCFWRev', UCHAR*8),             # 8    offset=86. Read Channel firmware version. Total=8 bytes
        ('FeatureFlags', ULONG),          # 4    offset=94. Feature flags
        ('Reserved98', ULONG),            # 4
        ('Reserved102', UCHAR*16),        # 16   offset=102 Reserved
        ('JumperSet', USHORT),            # 2    offset=118 Current no. of relo sectors on drive.
        ('ReloCnt', USHORT),              # 2    offset=120 Number of Tare Count
        ('TareCnt', USHORT),              # 2    offset=122 Number of Tares
        ('FTareCnt', USHORT),             # 2    offset=124 Number of Ftares
        ('RemRelo', USHORT),              # 2    offset=130 Max remaining possible relos
        ('ConsumedSpare', USHORT),        # 2    offset=128 No. of consumed spares.
        ('LastSpareLBAHigh', USHORT),     # 2    offset=130 Max Spare LBA high
        ('LastSpareLBALow', ULONG),       # 4    offset=132 Max Spare LBA low
        ('TPI', USHORT),                  # 2    offset=136 Selected KTPI
        ('AreaDensity', USHORT),          # 2    offset=138 Area density in units of 100MB per platter
        ('FormatType', UCHAR),            # 1    offset=140 Drive Format Type
        ('Unused141', UCHAR),             # 1    offset=141 unused
        ('ChipId', USHORT),               # 2    offset=142 controller chip familyt id
        ('PCBARev', UCHAR),               # 1    offset=144 Revision of PCBA
        ('Unused145', UCHAR*3),           # 3    offset=145 unused
        ('FeatureSupport1', ULONG),       # 4    offset=148 Features SupportedBit 0 = Enhanced Security1 to 63 reserved
        ('FeatureSupport2', ULONG),       # 4
        ('NumOTFSym', USHORT),            # 2    offset=156 Number of symbols that can be corrected by one interleave of OTF correction
        ('BurstSymCnt', USHORT),          # 2    offset=158 Number of symbols that can be corrected by firmware burst correction
        ('SymBitOffset', UCHAR),          # 1    offset=160 Number of bits between the start of the first symbol and the first bit in a sector
        ('Unused161', UCHAR*3),           # 3    offset=161 unused
        ('FlashSize', UCHAR),             # 1    offset=164 Size of flash, irrespective of type, in 16KB units
        ('FlashProtocolVer', UCHAR),      # 1    offset=165 Flash Programming Protocol Version
        ('FlashSectorSize', UCHAR),       # 1    offset=166 Flash Sector Size (in 2k units). This is the erasable block size of the flash and minimum size to be programmed.
        ('HeadFormatClass', UCHAR),       # 1    offset=167 what class is used for DDT and DRM
        ('HDAType', UCHAR*2),             # 2    offset=168 type of HDA (max number of platters)
        ('SlumberTimer', USHORT),         # 2    offset=170 SATA power management slumber timer
        ('PartialTimer', USHORT),         # 2    offset=172 SATA power management partial timer
        ('ReadTLER', USHORT),             # 2    offset=174 Current VAlue of read TLER in ms
        ('WriteTLER', USHORT),            # 2    offset=176 Current VAlue of Write TLER in ms
        ('CacheSize', ULONG),             # 4    offset=178 Actual num of 512 bytes buffers actually allocated to cache and not just DRAM overhead. This value may change as transient overlays and PST are loaded/unloaded
        ('DRAMSize', USHORT),             # 2    offset=182 Physical size of DRAM in MB. This field always returns actual size whereas ID Dev returns amount of DRAM used and maybe less
        ('UCCMCacheFam', ULONG),          # 4    offset=184 Current Dash Code configuration for the drive
        ('UCCMDashCode', ULONG),          # 4    offset=188 Current Dash Code configuration for the drive
        ('UCCMConfgVerMajor', USHORT),    # 2    offset=192 Major Version for the current dash code list
        ('UCCMConfgVerMinor', USHORT),    # 2    offset=194 Minor Version for the current dash code list
        ('UCCMFWStructVerMajor', USHORT), # 2    offset=196 F/W structure version
        ('UCCMFWStructVerMinor', USHORT), # 2    offset=198 F/W structure version
        ('UCCM_State', UCHAR*2),          # 2    offset=200 State of drive, whether user has tempered or not
        ('UCCM_CCC', ULONG*2),            # 4    offset=202 Customer Configuration Code (CCC)
        ('ModelNumber', UCHAR*40),        # 40   offset=210
        ('Reserved250', UCHAR*6),         # 6    offset=250
        ('DrvDataTblOverlay', Drv_Data_Tbl_Overlay),   # This starts at byte offset 256 of drvtbl data.
        ('PDListHashSzInBits', UCHAR),    # 1    offset=316 PDlist Hash Index size in number of bits.
        ('Reserved317', UCHAR),           # 1    offset=317
        ('SerialNumber', UCHAR*20),       # 20   offset=318
        ('Reserved338', UCHAR*26),        # 26   offset=338
        ('ProdID16', USHORT),             # 2    offset=364 16bit ProdID
        ('GlobProdID', USHORT),           # 2    offset=366 Globle Product ID
        ('CrystalFrequency', USHORT),     # 2    offset=368 Crystal Frequency in MHz
        ('DepopMap', USHORT),             # 2    offset=370
        ('MaxNumHeads', USHORT),          # 2    offset=372
        ('Reserved374', USHORT),          # 2    offset=374
        ('FirstUserAba', ULONG),          # 4    offset=376 First User Aba given by format
        ('Reserved380', UCHAR*6),         # 6    offset=380-385
        ('FlashManuID', ULONG),           # 4    offset=386-389
        ('FlashDeviceID', ULONG),         # 4    offset=390-393
        ('ZCPrioPoolDepth', USHORT),      # 2    offset=394
        ('Reserved396', UCHAR*116),       # 116  offset=396
    ]

# VSC Status Byte Map
class VSC_Status(Structure):
    _pack_ = 1
    _fields_ = [
        ('Ver', USHORT),            # 2    000-001 Format Version
        ('Minor', UCHAR),           # 1    002     VSC Implementation Version, Minor
        ('Major', UCHAR),           # 1    003     VSC Implementation Version, Major
        ('MaxActCode', USHORT),     # 2    004-005 Max Action Code supported
        ('LastCmdType', UCHAR),     # 1    006     Last Cmd Type
        ('LastCmd', UCHAR),         # 1    007     Last Cmd REgister value
        ('LastActCode', USHORT),    # 2    008-009 Last Action Code
        ('LastFeat', USHORT),       # 2    010-011 last Feature register value
        ('LastSC', USHORT),         # 2    012-013 last sector count register value
        ('LastSN', USHORT),         # 2    014-015 last sector number register value
        ('LastCyl', USHORT),        # 2    016-017 last cylinder (Ext. LBA Mid)
        ('LastLBAHigh', USHORT),    # 2    018-019 MS 16 bits (Extended commands only)
        ('DevCtrl', UCHAR),         # 1    020     Device control register
        ('DevHd', UCHAR),           # 1    021     Device/head register
        ('LastResp', USHORT),       # 2    022-023 MSB=Task file reg, LSB=Task file Error Reg
        ('ExtErr', USHORT),         # 2    024-025 Extended error status of last ATA or VSC Command
        ('VSCTXCntLo', ULONG),      # 4    026-029 No. of sector pending to be xferred to/from drive (Total=6 bytes)
        ('VSCTXCntHi', USHORT),     # 2    030-031 VSCTxCnt remaining 2 bytes
        ('TFData', USHORT),         # 2    032-033 task file data of last vsc command
        ('StatusFlg1', ULONG),      # 4    034-037 Status Flag 1
        ('StatusFlg2', ULONG),      # 4    038-041 Currently Not Used
        ('StatusFlg3', ULONG),      # 4    042-045 Currently Not Used
        ('CheckPoint', UCHAR),      # 1    046     Current DST or Offline activity
        ('APMLevel', UCHAR),        # 1    047     APM Level
        ('SecondaryEcode', USHORT), # 2    048-049 Secondary Error Code
        ('InitCode', ULONG),        # 4    050-053 Initiator Code
        ('CurState', UCHAR),        # 1    054     Current State
        ('CurState2', UCHAR),       # 1    055     Current State 2
        ('CurLBA', UCHAR*6),        # 1    056     LBA of last LBA accessed with or w/o error (total=6 bytes)
        # pad                       # 5    057-061 remaining bytes of CurLBA
        ('CurTrkOft', USHORT),      # 2    062-063 Current track offset
        ('CurVirCyl', ULONG),       # 4    064-067 virtual cylinder of current active track
        ('CurVirHd', UCHAR),        # 1    068     virtual head of current active track
        ('CurZone', UCHAR),         # 1    069     Current Data Zone
        ('CurWedgeStart', USHORT),  # 2    070-071 No. of counts from servo to start wedge (TOC or Data bits for SOC)
        ('CurWedgeSize', USHORT),   # 2    072-073 Size in bytes
        ('DTemp', UCHAR),           # 1    074     Current Drive Temperature value
        ('JTemp', UCHAR),           # 1    075     Current Junction Temperature value
        ('CTemp', USHORT),          # 2    076-077 Current Coil Temperature value
        ('SvStatus', USHORT),       # 2    078-079 servo status
        ('SvGpErr', USHORT),        # 2    080-081 servo group error
        ('Pad82', USHORT),          # 2    082-083
        ('SeedCyl', UCHAR*3),       # 1    084     ECC seed cyl of last read
        # pad                       # 2    085-086 remaining 2 bytes of seed Cyl
        ('SeedHead', UCHAR),        # 1    087 ECC seed head of last read
        ('SeedSector', USHORT),     # 2    088-089 ECC seed sector of last read
        ('SectorSkew', USHORT),     # 2    090-091 sector skew for current track
        ('WedgeSkew', USHORT),      # 2    092-093 wedge skew for current track
        ('Pad94', USHORT),          # 2    094-095 reserved
        ('DBSCode', ULONG),         # 4    096-099 Debug stop code
        ('DBSPara', ULONG),         # 4    100-103 Debug stop parameter
        ('BGProgress', USHORT),     # 2    104-105 Background process indicator
        ('FTemp', UCHAR),           # 1    106     Ftemp sensor temperature
        ('Rsvd1', UCHAR),           # 1    107     Reserved
        ('WrFaultLBALow', ULONG),   # 4    108-111 Write Fault LBA low (bits 0-31)
        ('WrFaultLBAHigh', USHORT), # 2    112-113 Write Fault LBA high (bits 32-47)
        ('CurCylOftSvo', USHORT),   # 2    114-115 Current Servo track Offset.  Same as CurTrkOft in Servo unit
        ('CurSvoCyl', ULONG),       # 4    116-119 Current Servo Cyl of currently active Servo track
        ('CurSvoOft', USHORT),      # 2    120-121 Track offset of currently active Servo track
        ('ConnectSpeed', UCHAR),    # 1    122     Current Host Connection speed
        ('Pad123', UCHAR*277),      # 277  123-399 reserved
        ('PTMId', USHORT),          # 2    400-401 file id of PTM currently executing
        ('TestId', USHORT),         # 2    402-403 test id of the PTM currently executing
        ('ActionCode', USHORT),     # 2    404-405 action code of VSC currently executing
        ('ExtErrCode', USHORT),     # 2    406-407 extended error code of last VSC command executed by PST
        ('ActionStatus', ULONG*6),  # 4    408-411 current status information specific to the AST module
        #pad                        # 20   412-431 remaining bytes for actionstatus
        ('Pad432', UCHAR*80),       # 80   432-511 remaining bytes till 512
    ]

class File_Header_48Byte(Structure):
    _pack_ = 1
    _fields_ = [
        ('file_header_version', ULONG), # 4  [Bytes 00:03] Hardcoded to 0x4c594f52 for FM_HEADER_II
        ('file_header_type', UCHAR),    # 1  [Byte 04]     1 for generic, 2 for PST, 3 for Overlay, 4 for flash
        ('reserved5', UCHAR),           # 1  [Byte 05]     Padding
        ('file_header_size', USHORT),   # 2  [Bytes 06:07] Offset to data in File, skip over the file header.
        ('file_id', USHORT),            # 2  [Bytes 08:09] 16 bit file id.
        ('file_size', USHORT),          # 2  [Bytes 10:11] Size in sectors (rounded up).
        ('checksum', ULONG),            # 4  [Bytes 12:15] 32 bit checksum.
        ('version', UCHAR*8),           # 8  [Bytes 16:23] version 8 chars including NULL
        ('month', UCHAR),               # 1  [Byte 24]     month in hex.
        ('day', UCHAR),                 # 1  [Byte 25]     day in hex
        ('year', UCHAR),                # 1  [Byte 26]     2 digit year in hex.
        ('reserved27', UCHAR),          # 1  [Byte 27]     pad
        ('description_string', USHORT), # 2  [Bytes 28:29] Offset in file to description string.
        ('fm_file_specific', ULONG*3),  # 12 [Bytes 30:41] Bytes 30:31 = Build ID to match against Flash Code.
        ('reserved42', UCHAR*6),        # 6  [Bytes 42:47]
    ]

class FM_File_Specific(Structure):
    _pack_ = 1
    _fields_ = [
        ('build_id', USHORT),
        ('reserved2', UCHAR*10),
    ]

class Config_Sector_Hdr48(Structure):
    _pack_ = 1
    _fields_ = [
        ('FILE_HEADER', File_Header_48Byte),
        ('NUM_CONFIG_SECTIONS', USHORT),
        ('SERIAL_NUMBER_OFFSET', USHORT),
        ('SERIAL_NUMBER_SIZE', USHORT),
        ('CAPACITY_CONFIG_OFFSET', USHORT),
        ('CAPACITY_CONFIG_SIZE', USHORT),
        ('FEATURE_CONTROL_OFFSET', USHORT),
        ('FEATURE_CONTROL_SIZE', USHORT),
        ('CACHE_CONFIG_2MB_OFFSET', USHORT),
        ('CACHE_CONFIG_2MB_SIZE', USHORT),
        ('MRM_RPO_CONFIG_2MB_OFFSET', USHORT),
        ('MRM_RPO_CONFIG_2MB_SIZE', USHORT),
        ('RSC_CONFIG_2MB_OFFSET', USHORT),
        ('RSC_CONFIG_2MB_SIZE', USHORT),
        ('DEFECT_MANAGEMENT_OFFSET', USHORT),
        ('DEFECT_MANAGEMENT_SIZE', USHORT),
        ('DISK_CONFIG_OFFSET', USHORT),
        ('DISK_CONFIG_SIZE', USHORT),
        ('SERVO_CONFIG_OFFSET', USHORT),
        ('SERVO_CONFIG_SIZE', USHORT),
        ('READ_CHANNEL_CONFIG_OFFSET', USHORT),
        ('READ_CHANNEL_CONFIG_SIZE', USHORT),
        ('SMART_CONFIG_OFFSET', USHORT),
        ('SMART_CONFIG_SIZE', USHORT),
        ('VSC_CONFIG_OFFSET', USHORT),
        ('VSC_CONFIG_SIZE', USHORT),
        ('BACKGROUND_CONFIG_OFFSET', USHORT),
        ('BACKGROUND_CONFIG_SIZE', USHORT),
        ('CDD_CONFIG_OFFSET', USHORT),
        ('CDD_CONFIG_SIZE', USHORT),
        ('ERROR_RECOVERY_OFFSET', USHORT),
        ('ERROR_RECOVERY_SIZE', USHORT),
        ('FORMAT_OFFSET', USHORT),
        ('FORMAT_SIZE', USHORT),
        ('MODEL_STRING_OFFSET', USHORT),
        ('MODEL_STRING_SIZE', USHORT),
        ('DRIVE_LABEL_OFFSET', USHORT),
        ('DRIVE_LABEL_SIZE', USHORT),
        ('PASSWORD_OFFSET', USHORT),
        ('PASSWORD_SIZE', USHORT),
        ('CACHE_CONFIG_8MB_OFFSET', USHORT),
        ('CACHE_CONFIG_8MB_SIZE', USHORT),
        ('MRM_RPO_CONFIG_8MB_OFFSET', USHORT),
        ('MRM_RPO_CONFIG_8MB_SIZE', USHORT),
        ('RSC_CONFIG_8MB_OFFSET', USHORT),
        ('RSC_CONFIG_8MB_SIZE', USHORT),
        ('SATA_SECTION_OFFSET', USHORT),
        ('SATA_SECTION_SIZE', USHORT),
    ]

# VDT Sector Physical Zone Table (For Action Code 13, Get Drive Data Table)
class Sect_Phys_Zone_Tbl_Hdr(Structure):
    _pack_ = 1
    _fields_ = [
        ('ver', USHORT),            # 2
        ('num_zones', UCHAR),       # 1
        ('curr_head', UCHAR),       # 1
        ('rsvd_data_cyls', USHORT), # 2
        ('max_virt_cyls', ULONG),   # 4
        ('rsvd_svo_cyls', USHORT),  # 2
        ('max_svo_cyls', ULONG),    # 4
        ('pad', UCHAR*34),          # 34
    ]

class Sect_Phys_Zone_Tbl(Structure):
    _pack_ = 1
    _fields_ = [
        ('first_cyl_zn', ULONG),    # 4
        ('last_cyl_zn', ULONG),     # 4
        ('first_servo_cyl', ULONG), # 4
        ('last_servo_cyl', ULONG),  # 4
        ('spt_hd0_zn', USHORT),     # 2
    ]

class Sect_Logical_Zone_Tbl_Hdr(Structure):
    _pack_ = 1
    _fields_ = [
        ('ver', USHORT),             # 2
        ('numzones', USHORT),        # 2
        ('numheads', USHORT),        # 2
        ('host_max_lo', ULONG),      # 4
        ('host_max_hi', USHORT),     # 2
        ('dco_max_lo', ULONG),       # 4
        ('dco_max_hi', USHORT),      # 2
        ('destroke_max_lo', ULONG),  # 4
        ('destroke_max_hi', USHORT), # 2
        ('process_max_lo', ULONG),   # 4
        ('process_max_hi', USHORT),  # 2
        ('format_max_lo', ULONG),    # 4
        ('format_max_hi', USHORT),   # 2
        ('first_spare_lo', ULONG),   # 4
        ('first_spare_hi', USHORT),  # 2
        ('last_spare_lo', ULONG),    # 4
        ('last_spare_hi', USHORT),   # 2
        ('pad', UCHAR*48),           # 48
   ]

class Sect_Logical_Zone_Tbl(Structure):
    _pack_ = 1
    _fields_ = [
        ('FirstLBALo_Zn', ULONG),  # 4
        ('FirstLBAHi_Zn', USHORT), # 2
        ('LastLBALo_Zn', ULONG),   # 4
        ('LastLBAHi_Zn', USHORT),  # 2
        ('SPTHd0_Zn', USHORT),     # 2
        ('SPTHd1_Zn', USHORT),     # 2
        ('SPTHd2_Zn', USHORT),     # 2
        ('SPTHd3_Zn', USHORT),     # 2
        ('SPTHd4_Zn', USHORT),     # 2
        ('SPTHd5_Zn', USHORT),     # 2
        ('SPTHd6_Zn', USHORT),     # 2
        ('SPTHd7_Zn', USHORT),     # 2
    ]

# Read/Reset Error Rate Table (For Action Code 15)
class ERate_Tbl_Hdr(Structure):
    _pack_ = 1
    _fields_ = [
        ('Ver', USHORT),      # 2
        ('NumZones', UCHAR),  # 1
        ('NumHds', UCHAR),    # 1
        ('Pad', UCHAR*28),    # 28
    ]

class ERate_Tbl_Entry(Structure):
    _pack_ = 1
    _fields_ = [
        ('NumSect', ULONG),     # 4 No. of sectors read or written
        ('NumOTFErr', ULONG),   # 4 No. of OTF errors
        ('NumDXErr', USHORT),   # 2 No. of DX Errors
        ('NumSvErr', USHORT),   # 2 No. of servo offtrk errors
        ('NumTAErr', USHORT),   # 2 No. of TA errors
        ('NumUnknown', USHORT), # 2 No. of Unknown errors
    ]

# Byte Map definition for the PST file type FHII.
class PST_Hdr(Structure):
    _pack_ = 1
    _fields_ = [
        ('StartAddress', ULONG), # 4 [Bytes 30:33] Start address
        ('LoadAddress', ULONG),  # 4 [Bytes 34:37] Load Address
        ('BytesInFile', ULONG),  # 4 [Bytes 38:41] Bytes in File
    ]

# Bytemap definition for the LBA Dirsector Entry
class LBA_Dir_Entry(Structure):
    _pack_ = 1
    _fields_ = [
        ('next_entry_offset', UCHAR), # 1 Number of bytes to next File ID.  Zero to indicate last entry.
        ('num_file_copy', UCHAR),     # 1 Number of copies this file has in the reserved area
        ('file_id', USHORT),          # 2 If FM_FILE_HEADER_II is enabled, now 2 bytes
        ('file_size', USHORT),        # 2 size of file in Sector
        ('file_attr', ULONG),         # 4 File attribute.
    ]

# Byte Map definition for the Packet FileList Entry fileheaderII
class File_List_Hdr(Structure):
    _pack_ = 1
    _fields_ = [
        ('next_entry_offset', UCHAR), # 1 [Byte 01]     Offset to next BmFileListHdr
        ('num_copies', UCHAR),        # 1 [Byte 02]
        ('file_id', USHORT),          # 2 [Bytes 03:04] 16 bit file id.
        ('file_size', USHORT),        # 2 [Bytes 05:06] Size in sectors (rounded up).
        ('file_attr', ULONG),         # 4 [Bytes 07:10] This file's attribute
        ('address', ULONG),           # 4 [Bytes 11:14] Starting address of file pointed to by this entry
        ('version_maj', ULONG),       # 4 [Bytes 15:18] version 8 chars including NULL
        ('version_min', ULONG),       # 4 [Bytes 19:22]
    ]

# BYTE Maps for VSC Key Sector
class Key_Sector(Structure):
    _pack_ = 1
    _fields_ = [
        ('action_code', USHORT), # 2
        ('param1', USHORT),      # 2
        ('param2', USHORT),      # 2
        ('param3', USHORT),      # 2
        ('param4', USHORT),      # 2
        ('param5', USHORT),      # 2
        ('param6', USHORT),      # 2
        ('param7', USHORT),      # 2
        ('param8', USHORT),      # 2
        ('param9', USHORT),      # 2
        ('param10', USHORT),     # 2
        ('param11', USHORT),     # 2
        ('param12', USHORT),     # 2
        ('param13', USHORT),     # 2
        ('param14', USHORT),     # 2
        ('param15', USHORT),     # 2
    ]

# Special BYTE Maps For VSC Execute File Key Sector
class XFile_Key_Sector(Structure):
    _pack_ = 1
    _fields_ = [
        ('action_code', USHORT), # 2
        ('func_code', USHORT),   # 2
        ('file_id', USHORT),     # 2
        ('test_id', USHORT),     # 2
        ('test_param1', ULONG),  # 4
        ('test_param2', ULONG),  # 4
        ('test_param3', ULONG),  # 4
        ('test_param4', ULONG),  # 4
        ('test_param5', ULONG),  # 4
        ('test_param6', ULONG),  # 4
        ('test_param7', ULONG),  # 4
        ('test_param8', ULONG),  # 4
        ('test_param9', ULONG),  # 4
        ('test_param10', ULONG), # 4
        ('test_param11', ULONG), # 4
        ('test_param12', ULONG), # 4
        ('test_param13', ULONG), # 4
        ('test_param14', ULONG), # 4
        ('test_param15', ULONG), # 4
        ('test_param16', ULONG), # 4
    ]

ext_err = -1
super_buffer = bytearray()
vsc_status = VSC_Status()
